package com.xinyue.ext.reader.dao;

import java.util.ArrayList;
import java.util.List;

import org.dom4j.Element;
import org.dom4j.Node;

import com.xinyue.ext.Label;
import com.xinyue.ext.data.FieldData;
import com.xinyue.ext.data.FinderData;
import com.xinyue.ext.exception.ManyException;
import com.xinyue.ext.reader.ParamHolder;
import com.xinyue.ext.util.StringUtil;

public class JoinProcess implements Label{
	private static ParamHolder holder;
	
	//私有构造器
	private JoinProcess() {
	}
	//内部类
	private static class SingletonHolder{
        private static JoinProcess instance = new JoinProcess();  
    }
	/**
	 * 获得对象实例
	 */
	public static JoinProcess getInstance(ParamHolder holder) {
		JoinProcess.holder = holder;
		return SingletonHolder.instance;
	}
	
	/**
	 * 
	 * @param many
	 * @throws ManyException
	 */
	public void joinRead(Element many) throws ManyException{
		List<FieldData> joins = holder.getEntity().getJoins();
		
		FieldData one = joins.get(0);
		FieldData two = joins.get(1);

		//映射对象查询处理1
		FinderData q_one = process(many, one, two);
		//映射对象查询处理2
		FinderData q_two = process(many, two, one);
		//映射对象删除处理1
		FinderData d_one = deleteProcess(many, one);
		//映射对象删除处理2
		FinderData d_two = deleteProcess(many, two);
		
		//注入
		List<FinderData> finds = new ArrayList<FinderData>();
		finds.add(q_one);
		finds.add(q_two);
		finds.add(d_one);
		finds.add(d_two);
		
		holder.getEntity().getDao().setMany(finds);
	}
	
	/**
	 * dao方法处理
	 * @param many
	 * @param query
	 * @param by
	 * @return
	 */
	private FinderData process(Element many, FieldData query, FieldData by) {
		FinderData data = new FinderData();
		
		Node n = many.selectSingleNode("join[@join-key='" + query.getName() + "']");
		String entity = n.valueOf("@entity");
		
		data.setMethod("query" + entity + "By" + StringUtil.firstUpper(by.getName()));
		data.setReturnType("List<" + entity + ">");
		data.setParams(by.getType() + " " + by.getName());
		//sql
		data.setState("select o from " + holder.getEntity().getClassName() + " a," + entity
			+ " o where o." + query.getName() + "=a." + query.getName() + " and a." + by.getName() + "=?");
		//setter
		List<String> set_two = new ArrayList<String>();
		set_two.add("q.setParameter(0, " + by.getName() + ");");
		data.setParamSetter(set_two);
		data.setWarning(true);
		
		holder.getDaoImpt().add(holder.getEntity().getBeanPackage() + "." + entity);
		return data;
	}
	
	/**
	 * dao方法处理
	 * @param many
	 * @param query
	 * @param by
	 * @return
	 */
	private FinderData deleteProcess(Element many, FieldData by) {
		FinderData data = new FinderData();
		
		data.setMethod("deleteBy" + StringUtil.firstUpper(by.getName()));
		data.setReturnType("Integer");
		data.setParams(by.getType() + " " + by.getName());
		//sql
		data.setState("delete " + many.attributeValue(name_) + " where " + by.getName() + "=:" + by.getName());
		//setter
		List<String> set = new ArrayList<String>();
		set.add("q.setParameter(0, " + by.getName() + ");");
		data.setParamSetter(set);
		data.setOnly(true);
		data.setQuery(false);
		
		return data;
	}
}
